home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Extravaganza - Disc 1
/
ShareWare Extravaganza 1 of 4 (The Ultimate Shareware Company).iso
/
grprogs
/
picutil.exe
/
MOVE.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-06-05
|
20KB
|
603 lines
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ PROGRAM = MOVE.ASM ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
CSEG SEGMENT PUBLIC BYTE
ASSUME CS:CSEG,DS:CSEG
CR EQU 0DH
LF EQU 0AH
FILENAME DB 128 DUP (0)
HANDLE_IN DW 0
TYPE_FROM DW 0 ;POINTS TO TYPE IN FILENAME
OPTIONS DB 128 DUP(0) ;OPTIONS
UP DW 0
DOWN DW 0
RIGHT DW 0
LEFT DW 0
DISK_BUFFER DD 0 ;DISK BUFFER OFFSET
;DISK BUFFER SEGMENT
;44 BYTES
IMG_NAME DB ' '
IMG_HEIGHT DW 0
IMG_WIDTH DW 0
IMG_WIDTH_BYTE DW 0
IMG_PIX_SIZE DW 1
IMG_PIX_FMT DW 0
IMG_COLOR DW 0
IMG_COMPRESS DW 0
READ_POINTER DW 44
DW 0
WRITE_POINTER DW 44
DW 0
BYTE_ADJUST DW 0
EIGHT DW 8
IMG DB 'IMG',0
TELL_HOW DB '┌─────────────────────────────────────────────────────────────┐',cr,lf
DB '│syntax = MOVE filename.IMG [u#],[d#],[r#],[l#] │',cr,lf
DB '├─────────────────────────────────────────────────────────────┤',cr,lf
DB '│filename.typ = name of image file....must have correct type │',cr,lf
DB '├─────────────────────────────────────────────────────────────┤',cr,lf
DB '│ u# = Number of pixels to move image up in file │',CR,LF
DB '│ d# = Number of pixels to move image down in file │',CR,LF
DB '│ r# = Number of pixels to move image right in file │',CR,LF
DB '│ l# = Number of pixels to move image left in file │',CR,LF
DB '│ # = (0 to 65535) │',CR,LF
DB '└─────────────────────────────────────────────────────────────┘',cr,lf
DB 7,'$'
OPEN_ERROR DB 'open error on input file',cr,lf,'$'
CREATE_ERROR DB 'create error on output file',cr,lf,'$'
TYPE_ERROR DB 'error in type of input file',cr,lf
Db 'must be IMG',cr,lf,'$'
NOT_IMP DB 'NOT IMPLIMENTED YET',CR,LF,'$'
SIZE_ERROR DB 'pixels to move exceed number of pixels in file',cr,lf,'$'
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ MOVE.ASM ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
MOVE PROC FAR
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ RETURN SETUP │
;└─────────────────────────────────────────────────────────────────────────────┘
CLD
CLI
MOV AX,CS ;TEMP STACK
MOV SS,AX ;
MOV ES,AX ;
MOV SP,OFFSET STACK ;
STI
PUSH DS ;
XOR AX,AX ;
PUSH AX ;
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ GET FILENAME FROM COMMAND LINE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV SI,82H ;START OF FILENAME
XOR CH,CH ;
MOV CL,DS:[SI-2] ;SIZE OF FILENAME
CMP CX,0 ;NO COMMANDS
JE GFN800 ;ERROR
MOV DI,OFFSET FILENAME ;STORE FILENAME HERE
GFN100:
LODSB ;GET CHARACTER
CMP AL,20H ;END OF FILENAME?
JE GFN700 ;YES....BRANCH
CMP AL,CR ;END OF COMMAND LINE?
JE GFN800 ;YES....ERROR
STOSB ;SAVE CHARACTER
CMP AL,'.' ;START OF TYPE
JNE GFN200 ;
MOV CS:TYPE_FROM,DI ;START OF TYPE
GFN200:
LOOP GFN100 ;GET ANOTHER CHARACTER
JMP SHORT GFN800 ;ERROR IF DONE ALREADY
GFN300:
LODSB ;GET CHARACTER
CMP AL,CR ;END OF COMMAND LINE?
JE GFN900 ;YES....ERROR
CMP AL,'a'
JB GFN400
CMP AL,'z'
JA GFN400
AND AL,0DFH ;CONVERT TO UPPER CASE
GFN400:
STOSB ;SAVE CHARACTER
LOOP GFN300 ;GET ANOTHER CHARACTER
JMP SHORT GFN800 ;ERROR IF DONE
GFN700: ;
MOV AL,0 ;
STOSB ;
MOV DI,OFFSET OPTIONS ;
LOOP GFN300
GFN800:
MOV DX,OFFSET TELL_HOW ;
JMP ERROR ;
GFN900:
MOV AL,0 ;PUT NULL AT END OF STRING
STOSB ;
CMP WORD PTR CS:TYPE_FROM,0 ;
JE GFN800 ;ERROR
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ FIND DISK MEMORY │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AX,OFFSET PROG_END ;
MOV BX,CS ;
MOV DS,BX
SHR AX,1 ;
SHR AX,1 ;
SHR AX,1 ;
SHR AX,1 ;
ADD BX,AX ;
INC BX ;
MOV WORD PTR DISK_BUFFER+2,BX ;
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHECK FOR CORRECT FILE TYPE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV SI,OFFSET IMG ;CHANGE TYPE ON FILENAME
MOV DI,TYPE_FROM ;
MOV CX,3 ;
AND BYTE PTR [DI],0DFH ;MAKE CAPITOL LETTER
AND BYTE PTR [DI+1],0DFH ;MAKE CAPITOL LETTER
AND BYTE PTR [DI+2],0DFH ;MAKE CAPITOL LETTER
REP CMPSB ;
JNE OIF050
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ OPEN INPUT FILE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AH,3DH ;OPEN FILE FOR READ/WRITE
MOV AL,2H ;
MOV DX,OFFSET FILENAME ;
INT 21H ;
JNC OIF100
OIF050:
MOV DX,OFFSET OPEN_ERROR ;
JMP ERROR
OIF100:
MOV HANDLE_IN,AX
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHECK FOR OPTIONS │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV SI,OFFSET OPTIONS
OPT100:
LODSB
CMP AL,0 ;END OF OPTIONS?
JE OPT900 ;YES GO ON
AND AL,0DFH
CMP AL,'U' ;UP
JNE OPT200
CALL GET_NUMBER
MOV UP,AX
JMP SHORT OPT100
OPT200:
CMP AL,'D' ;DOWN
JNE OPT300
CALL GET_NUMBER
MOV DOWN,AX
JMP SHORT OPT100
OPT300:
CMP AL,'R' ;DOWN
JNE OPT400
CALL GET_NUMBER
MOV RIGHT,AX
JMP SHORT OPT100
OPT400:
CMP AL,'L' ;LEFT
JNE OPT100
CALL GET_NUMBER
MOV LEFT,AX
JMP SHORT OPT100
OPT900:
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHECK FOR REDUNDANCE │
;└─────────────────────────────────────────────────────────────────────────────┘
CMP UP,0 ;MAKE SURE UP OR DOWN IS ZERO
JE CHK200
CMP DOWN,0
JE CHK200
MOV AX,UP
CMP AX,DOWN
JA CHK100
SUB DOWN,AX
MOV UP,0
JMP SHORT CHK200
CHK100:
SUB AX,DOWN
MOV DOWN,0
MOV UP,AX
CHK200:
CMP RIGHT,0
JE CHK900
CMP LEFT,0
JE CHK900
MOV AX,RIGHT
CMP AX,LEFT
JA CHK300
SUB LEFT,AX
MOV RIGHT,0
JMP SHORT CHK900
CHK300:
SUB AX,LEFT
MOV LEFT,0
MOV RIGHT,AX
CHK900:
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ READ IMG HEADER │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AH,3FH
MOV BX,HANDLE_IN
MOV CX,44
MOV DX,OFFSET IMG_NAME
INT 21H
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHECK FOR SIZE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AX,IMG_WIDTH
CMP LEFT,AX
JAE CHK950
CMP RIGHT,AX
JAE CHK950
MOV AX,IMG_HEIGHT
CMP UP,AX
JAE CHK950
CMP DOWN,AX
JB CHK999
CHK950:
MOV BX,HANDLE_IN ;CLOSE FILE
MOV AH,3EH ;
INT 21H ;
MOV DX,OFFSET SIZE_ERROR ;
JMP ERROR
CHK999:
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHECK FILE ACCESS DIRECTION │
;└─────────────────────────────────────────────────────────────────────────────┘
CMP DOWN,0
JNE CFA500
MOV CX,IMG_HEIGHT
SUB CX,UP
MOV AX,UP ;MOVE IMAGE UP
MUL IMG_WIDTH_BYTE
ADD READ_POINTER,AX
ADD READ_POINTER+2,DX
CFA100:
CALL READ_LINE
CALL HORIZ_ADJ
CALL WRITE_LINE
MOV AX,IMG_WIDTH_BYTE
ADD READ_POINTER,AX
JNC CFA200
INC READ_POINTER+2
CFA200:
ADD WRITE_POINTER,AX
JNC CFA300
INC WRITE_POINTER+2
CFA300:
LOOP CFA100
MOV CX,UP ;PUT BLANK LINES
CMP CX,0
JE CFA999
CALL CLEAR_BUFFER
CFA400:
CALL WRITE_LINE
ADD WRITE_POINTER,AX
JNC CFA450
INC WRITE_POINTER+2
CFA450:
LOOP CFA400
JMP SHORT CFA999
CFA500: ;MOVE IMAGE DOWN
MOV AX,IMG_HEIGHT ;LAST LINE IN FILE
MUL IMG_WIDTH_BYTE
ADD WRITE_POINTER,AX
ADD WRITE_POINTER+2,DX
MOV AX,IMG_HEIGHT ;ADJUST READ POINTER
SUB AX,DOWN
MOV CX,AX
MUL IMG_WIDTH_BYTE
ADD READ_POINTER,AX
ADD READ_POINTER+2,DX
CFA600:
CALL READ_LINE
CALL HORIZ_ADJ
CALL WRITE_LINE
MOV AX,IMG_WIDTH_BYTE
SUB READ_POINTER,AX
JNC CFA700
DEC READ_POINTER+2
CFA700:
SUB WRITE_POINTER,AX
JNC CFA800
DEC WRITE_POINTER+2
CFA800:
LOOP CFA600
MOV CX,DOWN
CALL CLEAR_BUFFER
CFA900:
CALL WRITE_LINE
SUB WRITE_POINTER,AX
JNC CFA950
DEC WRITE_POINTER+2
CFA950:
LOOP CFA900
CFA999:
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CLOSE FILES │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV BX,HANDLE_IN ;CLOSE FILE
MOV AH,3EH ;
INT 21H ;
JMP EXIT
ERROR:
MOV AX,CS
MOV DS,AX
MOV AH,9
INT 21H
EXIT:
RET ;
MOVE ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ GET NUMBER ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ GET NUMBER FOLLOWING COMMAND │
;└─────────────────────────────────────────────────────────────────────────────┘
GET_NUMBER PROC NEAR
PUSH BX
MOV BX,0
GN100:
CMP BYTE PTR [SI+BX],'0'
JB GN200
CMP BYTE PTR [SI+BX],'9'
JA GN200
INC BX
JMP SHORT GN100
GN200:
MOV AX,BX
CALL ASC2BIN
ADD SI,BX
POP BX
RET
GET_NUMBER ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ ASCII TO BINARY ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
DIVISOR DW 0,1
TEN DW 10,100,1000,10000
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ DS:SI = START OF ASCII STRING │
;│ AX = NUMBER OF CHARACTER IN STRING (1-5) │
;├─────────────────────────────────────────────────────────────────────────────┤
;│ AX = RETURNS BINARY NUMBER │
;└─────────────────────────────────────────────────────────────────────────────┘
PUBLIC ASC2BIN
ASC2BIN PROC NEAR
PUSH BX ;SAVE REGISTERS
PUSH CX ;
PUSH DX ;
PUSH SI ;
SHL AX,1 ;MAKE INTO WORD OFFSET
MOV BX,AX ;
PUSH SI ;
MOV SI,OFFSET DIVISOR ;
MOV CX,[SI+BX] ;DIVISOR
POP SI ;
XOR BX,BX ;CLEAR BINARY HOLD REGISTER
;
ASC100: ;
LODSB ;GET ASCII NUMBER
AND AL,0FH ;STRIP ASCII PART
XOR AH,AH ;
MUL CX ;
ADD BX,AX ;
CMP CX,1 ;DONE?
JE ASC300
MOV AX,CX ;GET DIVISOR
XOR DX,DX ;
DIV TEN ;DIVIDE IT BY TEN
MOV CX,AX ;PUT BACK IN DX
JMP SHORT ASC100 ;
ASC300:
MOV AX,BX ;PUT BINARY NUMBER IN AX
POP SI ;RESTORE REGISTERS
POP DX ;
POP CX ;
POP BX ;
RET
ASC2BIN ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ READ_LINE ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
READ_LINE PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH DS
MOV AL,0
MOV AH,42H
MOV BX,HANDLE_IN
MOV DX,READ_POINTER
MOV CX,READ_POINTER+2
INT 21H
MOV AH,3FH
MOV BX,HANDLE_IN
MOV CX,IMG_WIDTH_BYTE
LDS DX,DISK_BUFFER
INT 21H
POP DS
POP DX
POP CX
POP BX
RET
READ_LINE ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ WRITE_LINE ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
WRITE_LINE PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH DS
MOV AL,0
MOV AH,42H
MOV BX,HANDLE_IN
MOV DX,WRITE_POINTER
MOV CX,WRITE_POINTER+2
INT 21H
MOV AH,40H
MOV BX,HANDLE_IN
MOV CX,IMG_WIDTH_BYTE
LDS DX,DISK_BUFFER
INT 21H
POP DS
POP DX
POP CX
POP BX
RET
WRITE_LINE ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ HORIZ_ADJUST ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
HORIZ_ADJ PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH DS
PUSH ES
CMP LEFT,0
JE HA500
MOV AX,LEFT
XOR DX,DX
DIV EIGHT ;AX=NUMBER OF BYTES DX=PIXELS
CLD
PUSH DS
MOV CX,IMG_WIDTH_BYTE
SUB CX,AX
LES DI,DISK_BUFFER
LDS SI,DISK_BUFFER
MOV SI,AX
REP MOVSB ;SHIFT BYTES FIRST
POP DS
MOV CX,AX ;CLEAR REMAINING BYTES
INC CX
XOR AL,AL
REP STOSB
MOV CL,DL
MOV DI,0
HA200:
MOV AX,ES:[DI]
XCHG AH,AL
SHL AX,CL
MOV ES:[DI],AH
INC DI
CMP DI,IMG_WIDTH_BYTE
JNE HA200
JMP SHORT HA999 ;SHIFT PIXELS NEXT
HA500:
CMP RIGHT,0
JE HA999
MOV AX,RIGHT
XOR DX,DX
DIV EIGHT ;AX=NUMBER OF BYTES DX=PIXELS
STD
PUSH DS
MOV CX,IMG_WIDTH_BYTE
SUB CX,AX
LES DI,DISK_BUFFER
LDS SI,DISK_BUFFER
ADD DI,CS:IMG_WIDTH_BYTE
ADD SI,CS:IMG_WIDTH_BYTE
MOV BYTE PTR ES:[DI+1],0
SUB SI,AX
REP MOVSB ;SHIFT BYTES FIRST
POP DS
MOV CX,AX ;CLEAR REMAINING BYTES
XOR AL,AL
REP STOSB
MOV CL,DL
MOV DI,IMG_WIDTH_BYTE
HA800:
MOV AX,ES:[DI]
XCHG AH,AL
SHR AX,CL
MOV ES:[DI+1],AL
DEC DI
JNZ HA800
CLD
HA999:
POP ES
POP DS
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
RET
HORIZ_ADJ ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ CLEAR BUFFER░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
CLEAR_BUFFER PROC NEAR
PUSH AX
PUSH CX
PUSH DI
PUSH ES
XOR AX,AX
MOV CX,IMG_WIDTH_BYTE
LES DI,DISK_BUFFER
POP ES
POP DI
POP CX
POP AX
RET
CLEAR_BUFFER ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;╚═════════════════════════════════════════════════════════════════════════════╝
DB 64 DUP('STACK')
STACK EQU $
PROG_END EQU $
;╔═════════════════════════════════════════════════════════════════════════════╗
;╚═════════════════════════════════════════════════════════════════════════════╝
CSEG ENDS
END MOVE